package com.wmx.hb.mapper;

import com.wmx.hb.pojo.Emp;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.mapping.FetchType;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;
import java.util.Map;

/**
 * 员工实体对应的方法映射.
 * <p>
 * 1、无论是注解版还是配置版，都需要要为 Mapper 接口指定 @Mapper 注解，或者使用 @MapperScan 扫描所有 Mapper 接口
 * 2、当使用 @MapperScan 扫描 Mapper 接口时，接口上 @Mapper 注解可以不写.
 * 3、XxxMapper 接口可以在对应 xml Sql 映射的同时，也可以直接使用注解方式编写 Sql。
 * 4、每个 Mapper 接口中的方法名称不允许重复，必须唯一。
 *
 * @author wangMaoXiong
 * @version 1.0
 * @date 2021/7/4 16:25
 */
public interface EmpMapper {

    /**
     * 按顺序将实体类 Emp 第一个不为空的属性作为 where 查询条件
     *
     * @param emp
     * @return
     */
    List<Emp> getEmp(Emp emp);

    /**
     * 查询薪资在[start,end]之间的员工，start 为空时，不设下限，end 为空时，不设上限.
     *
     * @param paramMap
     * @return
     */
    List<Emp> getEmpBySal(Map<String, Double> paramMap);

    /**
     * 插入单条数据
     *
     * @param emp
     */
    void insertEmp(Emp emp);

    /**
     * 批量插入
     *
     * @param emps
     */
    void insertEmps(List<Emp> emps);

    /**
     * 批量插入
     *
     * @param emps
     */
    void batchInserts(List<Emp> emps);

    /**
     * 流式查询查询所有员工数据
     * 指定 Mapper 接口方法的返回值为 Cursor<T> 类型， MyBatis 自动识别它为流式查询。
     *
     * @return
     */
    @Select("select * from emp")
    Cursor<Emp> findAllEmps();

    /**
     * 根据主键查询员工信息——一对一关联查询员工所属的部门信息
     * <p>
     * 1、Results 用于映射结果的列与属性，不显示配置时，默认自动映射，映射不上的，值默认为 null.
     * 2、property 是实体的属性名称，或者 Map 的 key 。
     * 3、column 是表中的列名，即 emp 中的列名。存在关联关系时，它的值将作为参数传给 @One、@Many 关联的查询方法作为新的参数值.
     * 6、on：表示一对一，select 指定关联查询的方法名称，此时调用者 column 列的值会作为参数传给被调用方法。
     * * 如果是本类中的其它方法，则可以直接写方法名称，否则需要全限定类名.
     * 7、many：表示一对多，用法与 one 相同。
     * 8、column：如果对象中有关联对象，比如 一对一，员工关联部门，内连接一次性查询时，则属性名可以和 <resultMap> 标签一样，支持级联写，如 dept.deptno，此时可以省略 @One
     * * SELECT e.EMPNO,e.ENAME,e.JOB,e.MGR,e.HIREDATE,e.SAL,e.COMM,d.DEPTNO,d.DNAME,d.LOC FROM emp e LEFT JOIN dept d ON e.DEPTNO = d.DEPTNO
     *
     * @param empno
     * @return
     */
    @Results(value = {
            @Result(property = "dept", column = "deptno", one = @One(select = "com.wmx.hb.mapper.DeptMapper.findDeptById", fetchType = FetchType.DEFAULT))})
    @Select("select * from emp where empno = #{empno}")
    Emp getEmpById(int empno);

    /**
     * 根据姓名查询员工信息————一对一关联查询员工所属的部门信息
     *
     * @param ename
     * @return
     */
    List<Emp> getEmpByName(String ename);

    /**
     * 根据主键ID集合批量查询
     *
     * @param deptNo ：部门编号
     * @param ids    ：员工主键ID
     * @return
     */
    List<Emp> loadByIds(@Param("deptNo") Integer deptNo, @Param("ids") Integer[] ids);

    /**
     * 通过存储过程(函数)查询全部员工信息
     *
     * @return
     */
    List<Emp> proLoadAllEmps();

    /**
     * 通过存储过程(函数)查询指定部门下的员工信息
     *
     * @param deptNo
     * @return
     */
    List<Emp> proLoadEmpsByDeptno(@Param("deptNo") int deptNo);

    /**
     * 通过存储过程(函数)根据员工编号查询员工姓名
     * 注意：查询结果'姓名'是个字符串，必须使用 Map 或者 Java Bean 等对象进行接收。
     * * 不能使用下面的方式接收查询结果，此时字符串 eName 是接收不到值的。
     * * void proLoadEnameByEmpno(@Param("empNo") int empNo, @Param("eName") String eName);
     *
     * @param params ：员工编号使用 empNo，查询到的姓名结果为 eName
     */
    void proLoadEnameByEmpno(Map<String, Object> params);

    /**
     * 通过存储过程(函数)新增员工信息
     *
     * @param emp
     */
    void proSaveEmp(Emp emp);

}
